/**
 * 
 */
package it.battlehorse.scripting;

import it.battlehorse.rcp.sl.annot.Injected;
import it.battlehorse.rcp.sl.annot.Serviceable;
import it.battlehorse.scripting.mapping.ActionContributionMapper;
import it.battlehorse.scripting.mapping.IContributionMapper;
import it.battlehorse.scripting.mapping.ViewContributionMapper;
import it.battlehorse.scripting.registry.IScriptingRegistry;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ui.IStartup;


/**
 * Performs startup operations and add contributions the extension registry by converting
 * scripted contributions ( views, actions ) into standard contributions.
 * 
 * @author battlehorse
 *
 */
@Serviceable
public class ScriptingStartup implements IStartup, IScriptingConstants {

	private Log log ; 
	
	@Injected
	public void setLog(Log log) {
		this.log = log;
	} 

	private static Map<String,IContributionMapper> contribMapping;
	
	static {
		
		contribMapping = new HashMap<String,IContributionMapper>();
		contribMapping.put(EL_SCRIPTED_VIEW, new ViewContributionMapper());
		contribMapping.put(EL_SCRIPTED_ACTIONSET, new ActionContributionMapper());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IStartup#earlyStartup()
	 */
	public void earlyStartup() {
		
		if (!"true".equals(System.getProperty("eclipse.registry.nulltoken"))) {
			StringBuilder sb = new StringBuilder();
			sb.append("Automated contributions are disabled. Unable to add scripts contributions.\n");
			sb.append("Fix it with vm option \"-Declipse.registry.nulltoken=true\"");
			log.warn(sb.toString());
			return;
		}
		
		IScriptingRegistry sregistry = ScriptingActivator.getDefault().getScriptingRegistry();
		
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(ID_SCRIPTED_CONTRIBUTION);
		for (IExtension ext: point.getExtensions()) {
			IContributor contributor = ext.getContributor();
			for (IConfigurationElement el : ext.getConfigurationElements()) {
				IContributionMapper mapper = contribMapping.get(el.getName());
				if (mapper != null) {
					
					// delegates to the mapper the definition of the xml of the contribution
					String contribution = mapper.getContribution(el);
					
			    	InputStream is = new ByteArrayInputStream(contribution.getBytes());
			    	try {
			    		// Add contribution to the platform
				    	Platform.getExtensionRegistry().addContribution(is,
				    			contributor, 
				    			false, mapper.getContributionId(el), null, null);
				    	
				    	// Add script to the registry
				    	mapper.updateScriptingRegistry(sregistry, el);
				    	
				    	log.debug("Extension added: " + mapper.getContributionId(el));
			    	}
			    	catch(Exception e) {
			    		log.error("An error has occurred while adding contributions",e);
			    	}					
				}
			}
		}

	}

}